import React from "react";
import Draggable from "react-draggable";
import Resizable from "react-resizable-box";
import { drapPositions, drapEnd, confSrore } from "../service/store";

export class ChartContainer extends React.Component<{ style: any, Cmp: React.ComponentType<{ name: string }>, name: string }>{
  public origin = {
    width: '100%',
    height: '100%',
  }
  public ref: any

  public catch: any = {}

  public state = {
    data: [],
    width: this.origin.width,
    height: this.origin.height,
    activeDrags: 0,
    deltaPosition: {
      x: 0, y: 0
    },
    controlledPosition: {
      x: 0, y: 0
    },
    style: this.props.style
  }

  public onStart = (...args: any[]) => {
    this.setState({ activeDrags: ++this.state.activeDrags });
  }

  public onStop = (...args: any[]) => {
    drapEnd.next(this.props.name)
    this.setState({})
    this.setState({ activeDrags: --this.state.activeDrags });
  }

  public onControlledDrag = (e: any, position: any) => {
    const { x, y } = position;
    const positions: Array<[number, number]> = [
      [this.catch.offsetLeft + x, this.catch.offsetTop + y],
      [this.catch.offsetLeft + x + this.catch.clientWidth, this.catch.offsetTop + y],
      [this.catch.offsetLeft + x, this.catch.offsetTop + y + this.catch.clientHeight],
      [this.catch.offsetLeft + x + this.catch.clientWidth, this.catch.offsetTop + y + this.catch.clientHeight],
    ]
    console.log(this.catch, position)
    drapPositions.next(positions)
  }

  public componentDidMount() {
    this.calcCatch()
  }

  public componentWillReceiveProps(nextProps: any) {
    this.setState({ style: nextProps.style })
  }

  public render() {
    const dragHandlers = { onStart: this.onStart, onStop: this.onStop };
    // const {controlledPosition} = this.state;
    const R: any = Resizable
    const Cmp = this.props.Cmp
    return (
      <div ref={(ref) => this.ref = ref} style={{ position: 'absolute', ...this.state.style }} >
        <R
          style={{ position: 'absolute', right: 0, bottom: 0, top: 0, left: 0, background: 'aqua' }}
          width={this.state.width}
          height={this.state.height}
          onResize={(e: any, direction: any, ref: any, d: any) => {
            this.resize(direction, d);
          }}
          onResizeStop={() => {
            this.setState({ height: '100%', width: '100%' })
            drapEnd.next(this.props.name)
            setTimeout(() => {
              this.calcCatch()
            }, 500);
          }}
        >
          <Draggable position={{ x: 0, y: 0 }} onDrag={this.onControlledDrag} {...dragHandlers}>
            <div onClick={() => confSrore.next(this.props.name)} style={{ position: 'relative', height: '100%', width: '100%', background: 'red' }}>
              <Cmp name={this.props.name} />
            </div>
          </Draggable>
        </R>
      </div>
    )
  }

  private resize(direction: any, d: { width: number, height: number }) {
    if (direction === 'topLeft') {
      const style = { ...this.props.style, top: this.props.style.top - d.height, left: this.props.style.left - d.width }
      const positions: Array<[number, number]> = [
        [this.catch.offsetLeft - d.width, this.catch.offsetTop - d.height],
        [this.catch.offsetLeft + this.catch.clientWidth, this.catch.offsetTop - d.height],
        [this.catch.offsetLeft - d.width, this.catch.offsetTop + this.catch.clientHeight],
        [this.catch.offsetLeft + this.catch.clientWidth, this.catch.offsetTop + this.catch.clientHeight],
      ]
      drapPositions.next(positions);
      this.setState({
        width: this.origin.width + d.width,
        height: this.origin.height + d.height,
        style
      });
    } else if (direction === 'bottomRight') {
      const positions: Array<[number, number]> = [
        [this.catch.offsetLeft, this.catch.offsetTop],
        [this.catch.offsetLeft + this.catch.clientWidth + d.width, this.catch.offsetTop],
        [this.catch.offsetLeft, this.catch.offsetTop + d.height + this.catch.clientHeight],
        [this.catch.offsetLeft + d.width + this.catch.clientWidth, this.catch.offsetTop + d.height + this.catch.clientHeight],
      ];
      drapPositions.next(positions);
      this.setState({
        width: this.origin.width + d.width,
        height: this.origin.height + d.height,
      });
    } else if (direction === 'topRight') {
      const positions: Array<[number, number]> = [
        [this.catch.offsetLeft, this.catch.offsetTop - d.height],
        [this.catch.offsetLeft + this.catch.clientWidth + d.width, this.catch.offsetLeft + this.catch.clientWidth - d.height],
        [this.catch.offsetLeft, this.catch.offsetTop + this.catch.clientHeight],
        [this.catch.offsetLeft + this.catch.clientWidth + d.width, this.catch.offsetTop + this.catch.clientHeight],
      ];
      drapPositions.next(positions);
      const style = { ...this.props.style, top: this.props.style.top - d.height, left: this.props.style.left }
      this.setState({
        width: this.origin.width + d.width,
        height: this.origin.height + d.height,
        style
      });
    } else if (direction === 'bottomLeft') {
      const positions: Array<[number, number]> = [
        [this.catch.offsetLeft - d.width, this.catch.offsetTop],
        [this.catch.offsetLeft + this.catch.clientWidth, this.catch.offsetTop],
        [this.catch.offsetLeft - d.width, this.catch.offsetTop + d.height + this.catch.clientHeight],
        [this.catch.offsetLeft + this.catch.clientWidth, this.catch.offsetTop + d.height + this.catch.clientHeight],
      ];
      drapPositions.next(positions);
      const style = { ...this.props.style, top: this.props.style.top, left: this.props.style.left - d.width }
      this.setState({
        width: this.origin.width + d.width,
        height: this.origin.height + d.height,
        style
      });
    }
  }

  private calcCatch() {
    this.catch.offsetLeft = this.ref.offsetLeft
    this.catch.offsetTop = this.ref.offsetTop
    this.catch.clientHeight = this.ref.clientHeight
    this.catch.clientWidth = this.ref.clientWidth
  }
}